using System;
using System.Web.UI;
using System.IO;
using System.Text.RegularExpressions;
using anrControls.SyntaxColoring;
using System.Web.UI.WebControls;
using System.Web.Caching;
using System.Web.UI.HtmlControls;
using SharpPieces.Web;
using SharpPieces.Web.Controls;

namespace SharpPieces.DemoApp
{

    /// <summary>
    /// The Demo master page.
    /// </summary>
    public partial class Demo : MasterPage
    {

        // Fields

        internal static Regex codeFileRegex = new Regex("< *% *@ * *Page.*(CodeFile=\"(.*?)\"|CodeBehind=\"(.*?)\").*?% *>", RegexOptions.Compiled | RegexOptions.Singleline);
        internal static Regex descriptionRegex = new Regex("< *% *@ * *Page.*(Description=\"(.*?)\").*?% *>", RegexOptions.Compiled | RegexOptions.Singleline);
        internal static Regex titleRegex = new Regex("< *% *@ * *Page.*(Title=\"(.*?)\").*?% *>", RegexOptions.Compiled | RegexOptions.Singleline);


        // Methods

        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            // add aspx tab
            string aspxUnchangedCode;
            //this.AddCodePreview(this.Page.MapPath(this.Page.AppRelativeVirtualPath), out aspxUnchangedCode);

            //if (Demo.titleRegex.IsMatch(aspxUnchangedCode))
            //{
            //    Match titleMatch = Demo.titleRegex.Match(aspxUnchangedCode);
            //    if (titleMatch.Groups[2].Success && !string.IsNullOrEmpty(titleMatch.Groups[2].Value))
            //    {
            //        this.labelTitle.Text = titleMatch.Groups[2].Value;
            //    }
            //}

            // add the code tab
            //if (Demo.codeFileRegex.IsMatch(aspxUnchangedCode))
            //{
            //    Match codeFileMatch = Demo.codeFileRegex.Match(aspxUnchangedCode);
            //    //this.AddCodePreview(this.Page.MapPath(codeFileMatch.Groups[codeFileMatch.Groups[2].Success ? 2 : 3].Value));
            //}

            this.Load += new EventHandler(Demo_Load);
            this.PreRender += new EventHandler(Demo_PreRender);
        }

        void Demo_Load(object sender, EventArgs e)
        {
            //shows/hides adds and traking
            if (Request.Url.Host.IndexOf("localhost") > -1)
            {
                plTraking.Visible = false;
                plAdds.Visible = false;
            }
        }

        void Demo_PreRender(object sender, EventArgs e)
        {
            AddTabHeader("Demo", this.divDemoRuntime.ClientID);

            //add aspx code
            AddTab("ASPX", Server.MapPath(Request.RawUrl));

            //add cs code
            AddTab("ASPX.CS", Server.MapPath(Request.RawUrl)+".cs");
        }

        /// <summary>
        /// Handles the TreeNodeDataBound event of the treeSampleList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.TreeNodeEventArgs"/> instance containing the event data.</param>
        protected void treeSampleList_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Node.NavigateUrl))
            {
                e.Node.SelectAction = TreeNodeSelectAction.Expand;
            }
        }

        /// <summary>
        /// Adds a tab code preview; it should be called after Init.
        /// </summary>
        /// <param name="tabName">Tab name.</param>
        /// <param name="tabTitle">Tab title.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="unchangedCode">The unchanged file code.</param>
        public void AddTab(string tabName, string fileName)
        {
            if (null == tabName)
            {
                throw new ArgumentNullException("tabName");
            }

            string tabCode = tabName.Replace(" ", string.Empty);

            if (string.Empty == tabCode)
            {
                throw new ArgumentException("Invalid tabName value.");
            }

            if (null != this.divTabContainer.FindControl(tabName))
            {
                throw new ArgumentException("The tab having the same name already exists.");
            }

            if (null == fileName)
            {
                throw new ArgumentNullException("fileName");
            }

            FileInfo file = new FileInfo(fileName);
            if (!file.Exists)
            {
                return;
            }

            // read and highlight the code
            Language lang = SyntaxHighlighter.LanguageFromExtension(file.Extension);
            string code = "";
            //TODO: cache
            code = File.ReadAllText(file.FullName);

            Panel container = new Panel();
            //container.ID = tabCode+"Container";
            container.EnableViewState = false;
            //no padding for source!!!
            container.Style.Add(HtmlTextWriterStyle.Padding, "0px");

            this.divTabContainer.Controls.Add(container);
            
            SyntaxHighlighter sh = new SyntaxHighlighter();
            sh.Language = lang;
            sh.ContentTemplate = code;
            container.Controls.Add(sh);
            sh.UseTextArea = false; // text areas mess up with the form

            // add tab head
            AddTabHeader(tabName, container.ClientID);
            
        }

        private void AddTabHeader(string tabName, string contentID)
        {
            HtmlGenericControl spanTab = new HtmlGenericControl("span");
            spanTab.EnableViewState = false;
            spanTab.InnerText = tabName;

            HtmlAnchor aTab = new HtmlAnchor();
            aTab.EnableViewState = false;
            aTab.HRef = string.Format("#{0}", contentID);
            aTab.Controls.Add(spanTab);

            HtmlGenericControl liTab = new HtmlGenericControl("li");
            liTab.EnableViewState = false;
            liTab.Controls.Add(aTab);
            this.ulTabHeaderList.Controls.Add(liTab);
        }

        public void AddTab(string tabName, Panel content)
        {
            AddTabHeader(tabName, content.ClientID);
        }

        public bool ShowDemoRuntime
        {
            set { this.pnlDemoSrc.Visible = this.divDemoRuntime.Visible = value; }
        }

    }

}